from . import models
from rest_framework import serializers
from django.contrib.auth.hashers import check_password

class UserSerializer(serializers.ModelSerializer):
    '''
        序列化器：
            接受的参数 就是request.data
            根据已有的字段进行关联
            username 
            password
            password2
            email
            mobile
    '''
    password2 = serializers.CharField(
        min_length=8,
        max_length=20,
        required=True, # 那个data里必须得有一个叫password2的字段
        write_only=True, # 只能被填写 不能被返回
        error_messages={
            'min_length': '太短了',
            'max_length': '太长了',
        }
        # 错误做键 ，value为错误信息
    )
    # 反序列化才有password2去接收 write_only 别人给我的
    # 序列化返回的时候 数据库里是没有password2，是不需要返回的 
    # read_only 我给别人的 是不需要给password2
    password = serializers.CharField(
        min_length=8,
        max_length=20,
        required=True, # 那个data里必须得有一个叫password2的字段
        write_only=True, # 只能被填写 不能被返回
        error_messages={
            'min_length': '太短了',
            'max_length': '太长了',
        }
        # 错误做键 ，value为错误信息
    ) 
    # 有两种校验方式

    #字段校验 zhangsan 
    def validate_username(self,value):
        # value-> username
        if value == 'zhangsan':
            raise serializers.ValidationError('你不能用zhangsan作为用户名')
            #user.errors username:你不能用zhangsan作为用户名
        return value

    #整体校验 
    def validate(self,attrs):
        # attrs == request.data 是一个整体数据属性
        if attrs['password'] != attrs['password2']:
            raise serializers.ValidationError('两次密码不一样')
        return attrs

    # POST提交数据 存储 
    # create 创建
    # update 修改

    # request.data 
    def create(self,validate):
        # validate == attrs
        del validate['password2'] # 删除冗余字段
        user = models.Users.objects.create_user(**validate) # 创建用户
        # Users: admin界面下的 create_user
        # name =name #命名传参
        return user
        
    class Meta:
        '''
            models定义的时候
            进行表约束，设置一些表属性
        '''
        fields = ('username', 'password', 'password2', 'email', 'mobile')
        # 篮子的类型
        model = models.Users
        # 代表当前以上的篮子 中有的字段 只要在models中有，
        # 就会自动关联，使用models定义的字段类型

'''
    将对象反序列化用到的是 data传参
    socialuser = serializer.socialuserSerializer(data=queryDict_socialuser,context={'outer_key':users})
    将数据序列化用到的是 instance传参
    data_socialuser = serializer.socialuserSerializer(instance=socialuser_data)
    将对象序列化后传给前端是 data_socialuser.data
'''
# 用户社交表 反序列化器

class socialuserSerializer(serializers.ModelSerializer):
    # 外键字段设为可读字段   是为了序列化查询用的
    # PrimaryKeyRelatedField：只显示外键关联对象的主键ID
    user = serializers.PrimaryKeyRelatedField(read_only=True)
    
    class Meta:

        fields = "__all__"
        model = models.SocialUser   # 指定的表
        related_name='user_info'
    def create(self,validated_data):
        
        #                                     反序列化入库外键对象要传参过来  user：表外键字段
        users = models.SocialUser.objects.create(user=self.context['outer_key'],**validated_data)   # 创建用户

        return users

class ChangeUserPasswordSerializer(serializers.Serializer):
    # read_only 我给别人的 是不需要给password2
    old_password = serializers.CharField(
        min_length=8,
        max_length=20,
        required=True, # 那个data里必须得有一个叫password2的字段
        write_only=True, # 只能被填写 不能被返回
        error_messages={
            'min_length': '太短了',
            'max_length': '太长了',
        }
    )    

    new_password = serializers.CharField(
        min_length=8,
        max_length=20,
        required=True, # 那个data里必须得有一个叫password2的字段
        write_only=True, # 只能被填写 不能被返回
        error_messages={
            'min_length': '太短了',
            'max_length': '太长了',
        }
    )
    def validata_bew_password(self,value):
        if len(value) < 8 or len(value) >20:
            raise serializers.ValidationError('密码长度有问题')

    def update(self,instance,validate):
           # instance -> 序列化 -> userobject
            # 旧有的数据对象
        # data 传入来的校验过后的密码        
        old_password = validate['old_password']
        new_password = validate['new_password']

        if check_password(old_password,instance.password):
            # 校验没毛病，赋值新密码
            instance.set_password(new_password)
            instance.save()
        else:
            raise serializers.ValidationError('旧密码输入错误')
        return instance

class ResetpassSerializer(serializers.Serializer):
    password = serializers.CharField(
        min_length=8,
        max_length=20,
        required=True, # 那个data里必须得有一个叫password2的字段
        write_only=True, # 只能被填写 不能被返回
        error_messages={
            'min_length': '太短了',
            'max_length': '太长了',
        }
        # 错误做键 ，value为错误信息
    )    
    def update(self,instance,validate):
        instance.set_password(validate['password'])
        instance.save()
        return instance

class AreaSerialzer(serializers.ModelSerializer):
    class Meta:
        model = models.Areas
        fields = ('id','name')

# 地址表序列化器
class addressSerializer(serializers.ModelSerializer):

    # 外键字段设为可读字段   是为了序列化查询用的
    # PrimaryKeyRelatedField：只显示外键关联对象的主键ID
    user = serializers.PrimaryKeyRelatedField(read_only=True)

    # 指定反序列化入库的外键
    province = serializers.IntegerField(label='省ID', write_only= True)
    city = serializers.IntegerField(label='市ID', write_only= True)
    town = serializers.IntegerField(label='区ID', write_only= True)


     # 序列化输出   外键入库的是ID，但我需要查询出来的是 名字，这里定义外键输出类型
    province = serializers.StringRelatedField(read_only=True)
    city = serializers.StringRelatedField(read_only=True)
    town = serializers.StringRelatedField(read_only=True)

    
    class Meta:

        fields = "__all__"
        model = models.Address   # 指定的表

    def create(self,validated_data):
        
        #  反序列化入库外键对象要传参过来  user：表外键字段
        users = models.Address.objects.create(
            user=self.context['user'],
            province=self.context['province'],
            city=self.context['city'],
            town=self.context['town'],
            **validated_data
            )   # 创建用户

        return users